<template>
  <el-table
    ref="table"
    :data="tableData"
    :border="border"
    :stripe="stripe"
    :tooltip-effect="tooltipEffect"
    :style="styleObj"
    :highlight-current-row="highlight"
    :row-key="rowKey"
    :height="height"
    class="ym-table"
    @filter-change="filterChange"
    @row-click="handleRowClick"
  >
    <template #empty>
      <div v-if="setEmpty">
        <slot name="setEmpty"></slot>
      </div>
      <div v-else>
        <el-empty />
      </div>
    </template>
    <slot>
      <el-table-column v-if="selectShow" type="selection" :width="selectWidth" />
      <el-table-column
        v-for="item in columnData"
        :key="item.prop"
        :sortable="item.sortable"
        :type="item.type"
        :prop="item.prop"
        :label="item.label"
        :column-key="item.prop"
        :width="item.width"
        :min-width="item.minWidth"
        :formatter="item.formatter"
        :fixed="item.fixed"
        :align="item.align"
        :show-overflow-tooltip="!item.hiddenOverflowTooltip"
        :filters="item.filters"
        :filter-multiple="item.filterMultiple"
      >
        <template #default="scope">
          <slot
            v-if="item.slotname"
            :name="item.slotname"
            :row="scope.row"
            :item="scope.row[item.prop]"
            :index="scope.$index"
          ></slot>
          <span v-else>{{ scope.row[item.prop] }}</span>
        </template>
      </el-table-column>
      <el-table-column
        v-if="operatorShow"
        :fixed="isFixed ? 'right' : false"
        label="操作"
        :width="operatorWidth"
      >
        <template #default="scope">
          <slot name="operator" :row="scope.row" :index="scope.$index"></slot>
        </template>
      </el-table-column>
    </slot>
  </el-table>
</template>

<script lang="ts" setup>
import { CSSProperties, nextTick, onMounted, onUnmounted, PropType, ref } from 'vue'

import IBaseObj from '#/index'

const props = defineProps({
  rowKey: {
    type: String,
    default: 'id',
  },
  tableData: {
    type: Array as PropType<IBaseObj[]>,
    default: () => [],
  },
  columnData: {
    type: Array as PropType<IBaseObj[]>,
    default: () => [],
  },
  border: {
    type: Boolean,
    default: false,
  },
  stripe: {
    type: Boolean,
    default: false,
  },
  tooltipEffect: {
    type: String as PropType<'dark' | 'light'>,
    default: 'light',
    validator: (val: string) => {
      return ['dark', 'light'].includes(val)
    },
  },
  styleObj: {
    type: Object as PropType<CSSProperties>,
    default: () => {
      return { width: '100%' }
    },
  },
  highlight: {
    type: Boolean,
    default: true,
  },
  operatorWidth: {
    default: 120,
    type: [String, Number],
  },
  autoFixed: {
    type: Boolean,
    default: false,
  },
  operatorFixed: {
    type: Boolean,
    default: true,
  },
  operatorShow: {
    type: Boolean,
    default: true,
  },
  selectShow: {
    type: Boolean,
    default: false,
  },
  setEmpty: {
    type: Boolean,
    default: false,
  },
  height: {
    type: String,
    default: '100%',
  },
  needClickSelect: {
    type: Boolean,
    default: false,
  },
  selectWidth: {
    type: [String, Number],
    default: 55,
  },
})

const emits = defineEmits(['onFilterChange', 'row-click', 'row-db-click'])

const table = ref()

const isFixed = ref(false)

const setFixed = async () => {
  if (props.autoFixed) {
    await nextTick(() => {
      const val = table.value as any
      const tableEle = val.$el
      const width = tableEle.offsetWidth
      const tableBodyEle = tableEle.querySelector('.el-table__body-wrapper .el-table__body')
      const subWidth = parseInt(tableBodyEle.style.width)
      if (subWidth > width + 17) {
        isFixed.value = true
      } else {
        isFixed.value = false
      }
    })
  } else {
    isFixed.value = props.operatorFixed
  }
}

const filterChange = (filters: IBaseObj) => {
  emits('onFilterChange', filters)
}

const _resizeHandle = () => {
  setFixed()
}

onMounted(() => {
  setFixed()
  window.addEventListener('resize', _resizeHandle)
})

onUnmounted(() => {
  window.removeEventListener('resize', _resizeHandle)
})

const setCurrentRow = (row: IBaseObj | null) => {
  row && table.value?.setCurrentRow(row)
}

const doLayout = () => {
  table.value?.doLayout()
}

const toggleRowSelection = (row: IBaseObj, selected?: Boolean) => {
  table.value?.toggleRowSelection(row, selected)
}

const handleRowClick = (row: IBaseObj, column: IBaseObj, event: Event) => {
  const { selectShow, needClickSelect } = props

  if (selectShow && needClickSelect) {
    toggleRowSelection(row)
  }
  emits('row-click', row, column, event)
}

defineExpose({
  setCurrentRow,
  doLayout,
  toggleRowSelection,
})
</script>
